/**
 * 表格工具类
 * @description 提供表格导出、列宽记忆等实用功能
 * @version 4.0.0
 */

import { Local } from '/@/utils/storage'
import { ElMessage, ElMessageBox } from 'element-plus'
import * as XLSX from 'xlsx'

/**
 * 下载文件工具函数
 * @param content 文件内容
 * @param fileName 文件名
 * @param contentType 内容类型
 */
function downloadFile(content: string | Blob, fileName: string, contentType: string) {
    try {
        const a = document.createElement('a');
        
        let file: Blob;
        if (content instanceof Blob) {
            file = content;
        } else {
            file = new Blob([content], { type: contentType });
        }
        
        a.href = URL.createObjectURL(file);
        a.download = fileName;
        a.click();
        
        // 清理URL对象，避免内存泄漏
        setTimeout(() => {
            URL.revokeObjectURL(a.href);
        }, 100);
    } catch (error) {
        console.error('下载文件失败:', error);
        ElMessage.error('下载文件失败，请检查浏览器设置或权限');
    }
}

/**
 * 表格工具类 - 简化版
 * 专注于提供表格辅助功能，如列宽记忆、数据导出等
 */
export default class BaTableClass {
    /**
     * 表格ID
     */
    tableId: string;
    
    /**
     * 列宽记忆功能是否启用
     */
    rememberColumnWidth: boolean;
    
    /**
     * 列宽映射
     */
    columnWidths: Map<string, number>;
      /**
     * 构造函数
     * @param options 配置选项
     */
    constructor(options: {
        tableId?: string;
        rememberColumnWidth?: boolean;
    } = {}) {
        // 初始化属性
        this.tableId = options.tableId || 'table_' + Math.random().toString(36).substring(2, 9);
        this.rememberColumnWidth = options.rememberColumnWidth !== false;
        this.columnWidths = new Map<string, number>();
        
        // 加载保存的列宽设置
        if (this.rememberColumnWidth) {
            this.loadColumnWidths();
        }
    }
    
    /**
     * 处理行拖拽完成事件
     * 保留此方法以兼容现有组件
     */
    onRowDragEnd(oldIndex: number, newIndex: number, callback?: (rows: TableRow[]) => Promise<boolean>) {
        console.warn('此方法仅为兼容性保留，请考虑在组件中实现行拖拽逻辑');
    }
    
    /**
     * 处理列拖拽完成事件
     * 保留此方法以兼容现有组件
     */
    onColumnDragEnd(oldIndex: number, newIndex: number) {
        console.warn('此方法仅为兼容性保留，请考虑在组件中实现列拖拽逻辑');
    }
    
    /**
     * 保存列宽设置到本地存储
     */
    saveColumnWidths() {
        if (!this.tableId || !this.rememberColumnWidth) return;
        
        try {
            // 将 Map 转换为普通对象进行存储
            const widthsObject: Record<string, number> = {};
            
            this.columnWidths.forEach((width, prop) => {
                widthsObject[prop] = width;
            });
            
            Local.set(`table_column_widths_${this.tableId}`, widthsObject);
        } catch (error) {
            console.error('保存列宽设置失败:', error);
        }
    }
    
    /**
     * 从本地存储加载列宽设置
     */
    loadColumnWidths() {
        if (!this.tableId || !this.rememberColumnWidth) return;
        
        try {
            const savedWidths = Local.get(`table_column_widths_${this.tableId}`);
            if (!savedWidths) return;
            
            // 清除现有设置
            this.columnWidths.clear();
            
            // 加载保存的设置
            Object.entries(savedWidths).forEach(([prop, width]) => {
                this.columnWidths.set(prop, width as number);
            });
        } catch (error) {
            console.error('加载列宽设置失败:', error);
        }
    }
    
    /**
     * 更新列宽设置
     * @param prop 列标识
     * @param newWidth 新宽度
     */
    updateColumnWidth(prop: string, newWidth: number) {
        if (!this.rememberColumnWidth) return;
        
        try {
            // 保存到本地缓存
            this.columnWidths.set(prop, newWidth);
            this.saveColumnWidths();
        } catch (error) {
            console.error('更新列宽设置失败:', error);
        }
    }
    
    /**
     * 获取列宽设置
     * @param prop 列标识
     * @returns 列宽度 (如果未设置则返回 undefined)
     */
    getColumnWidth(prop: string): number | undefined {
        return this.columnWidths.get(prop);
    }
    
    /**
     * 重置所有列宽设置
     */
    resetColumnWidths() {
        try {
            this.columnWidths.clear();
            
            if (this.tableId) {
                Local.remove(`table_column_widths_${this.tableId}`);
            }
            
            ElMessage.success('列宽设置已重置');
        } catch (error) {
            console.error('重置列宽设置失败:', error);
            ElMessage.error('重置列宽设置失败');
        }
    }
    
    /**
     * 导出表格数据
     * @param options 导出选项
     */
    exportTable(options: {
        filename?: string;
        type?: 'csv' | 'excel';
        columns: TableColumn[];
        data: TableRow[];
    }) {
        const { filename = '导出数据', type = 'excel', columns, data } = options;
        
        try {
            // 检查是否有数据可导出
            if (!data || !columns) {
                ElMessage.warning('没有数据可导出');
                return;
            }
            
            // 如果数据为空，提示用户
            if (data.length === 0) {
                ElMessage.warning('当前没有数据可导出');
                return;
            }
            
            // 确认大数据量导出
            if (data.length > 1000) {
                ElMessageBox.confirm(
                    `当前数据量较大 (${data.length} 条记录)，导出可能需要较长时间，是否继续？`,
                    '确认导出',
                    {
                        confirmButtonText: '继续导出',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }
                ).then(() => {
                    this.executeExport(filename, type, columns, data);
                }).catch(() => {
                    // 用户取消导出
                });
                return;
            }
            
            // 执行导出
            this.executeExport(filename, type, columns, data);
        } catch (error) {
            console.error('导出表格失败:', error);
            ElMessage.error('导出失败，请稍后重试');
        }
    }
      /**
     * 执行导出操作
     * @private
     */
    private executeExport(
        filename: string,
        type: 'csv' | 'excel',
        columns: TableColumn[],
        data: TableRow[]
    ) {
        try {
            // 只导出可见列
            const visibleColumns = columns.filter(col => col.show !== false);
            
            if (visibleColumns.length === 0) {
                ElMessage.warning('没有可见列可导出');
                return;
            }
            
            // 构建表头
            const headers = visibleColumns.map(col => col.label || col.prop || '');
            
            // 构建行数据
            const rows = data.map(row => {
                return visibleColumns.map(col => {
                    const prop = col.prop as string;
                    // 安全获取数据，确保即使值为undefined或null也能正确处理
                    return row[prop] !== undefined && row[prop] !== null ? row[prop] : '';
                });
            });
            
            // CSV格式导出
            if (type === 'csv') {
                // 添加BOM以支持中文
                let csvContent = '\uFEFF';
                
                // 添加表头
                csvContent += headers.map(header => `"${String(header).replace(/"/g, '""')}"`).join(',') + '\r\n';
                
                // 添加数据行
                rows.forEach(row => {
                    csvContent += row.map(value => {
                        // 处理特殊字符，如双引号和逗号
                        const strValue = String(value);
                        return `"${strValue.replace(/"/g, '""')}"`;
                    }).join(',') + '\r\n';
                });
                
                // 下载文件
                downloadFile(csvContent, `${filename}.csv`, 'text/csv;charset=utf-8');
                
                ElMessage.success('CSV文件导出成功');
            }
            // Excel格式导出
            else if (type === 'excel') {
                // 构建工作表数据，包括表头
                const wsData = [headers, ...rows];
                
                // 创建工作表
                const ws = XLSX.utils.aoa_to_sheet(wsData);
                
                // 创建工作簿并添加工作表
                const wb = XLSX.utils.book_new();
                XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
                  // 自动设置列宽
                const colWidths = headers.map((header, idx) => {
                    // 计算表头宽度
                    let maxWidth = String(header).length * 1.5;
                      // 计算数据最大宽度
                    rows.forEach(row => {
                        const cellValue = String(row[idx] || '');
                        maxWidth = Math.max(maxWidth, cellValue.length * 1.5);
                    });
                    
                    // 限制最大和最小宽度
                    return { wch: Math.min(Math.max(maxWidth, 6), 50) };
                });
                
                ws['!cols'] = colWidths;
                
                // 导出Excel文件
                XLSX.writeFile(wb, `${filename}.xlsx`);
                
                ElMessage.success('Excel文件导出成功');
            }
        } catch (error) {
            console.error('执行导出失败:', error);
            ElMessage.error('导出失败，请稍后重试');
        }
    }
}
